package de.lulusoft.anothertorrent.gui.views;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.part.ViewPart;

import de.lulusoft.anothertorrent.core.AnotherTorrentCore;
import de.lulusoft.anothertorrent.core.servers.Server;
import de.lulusoft.anothertorrent.gui.commands.SendConsoleToServerCommand;
import de.lulusoft.anothertorrent.gui.util.Util;

public class ConsoleView extends ViewPart {
	
	public static final String ID = "de.lulusoft.anothertorrent.gui.views.ConsoleView";
	
	private static final String STATE_SERVER = "STATE_SERVER";
	
	private Composite mainComp = null;
	private StyledText txtServer = null;
	private Text txtUser = null;
	private Server server;
	private Button clearCmd = null;
	private ConsoleView me = null;

	public ConsoleView() {
		me = this;
	}
	
	public void setInput(Server input)
	{
		server = input;
		setPartName("XmlRPC Console: " + server.getName());
	}
	
	@Override
	public void saveState(IMemento memento) {
		super.saveState(memento);
		ByteArrayOutputStream  os = new ByteArrayOutputStream();
		ObjectOutputStream oOut = null;
		try {
			oOut = new ObjectOutputStream(os);
			oOut.writeObject(server);
			oOut.flush();
			String tmp = Util.convertBytesToHex(os.toByteArray());
			memento.putString(STATE_SERVER, tmp);
		} catch (IOException e) {
			e.printStackTrace();
		} finally 
		{
			try {
				oOut.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		if (memento == null)
			return;
		String state = memento.getString(STATE_SERVER);
		if (state != null)
		{
			try {
				byte bstate[] = Util.convertHexStringToBytes(state);
				ByteArrayInputStream is = new ByteArrayInputStream(bstate);
				ObjectInputStream ois = new ObjectInputStream(is);
				Server srv = (Server) ois.readObject();
				this.server = AnotherTorrentCore.getDefault().getServerManager().getServerByName(srv.getName());
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void createPartControl(Composite parent) {
		
		parent.setLayout(new FillLayout());
		mainComp = new Composite(parent, SWT.NONE);
		mainComp.setLayout(new GridLayout(2, false));
		
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 3);
		txtServer = new StyledText(mainComp, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER 
				| SWT.READ_ONLY | SWT.H_SCROLL);
		txtServer.setEnabled(true);
		txtServer.setLayoutData(gd);
		gd = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		txtUser = new Text(mainComp, SWT.NONE | SWT.BORDER);
		txtUser.setLayoutData(gd);
		txtUser.setEditable(true);
		txtUser.setEnabled(true);
		txtUser.setBackground(new Color(Display.getDefault(),200,200,200));
		txtUser.setText("system.listMethods");
		txtUser.addKeyListener(new KeyListener() {
		
			@Override
			public void keyReleased(KeyEvent e) 
			{
				if (e.keyCode == 13 || e.keyCode == 16777296) // Both Enters..
				{
					if (txtUser.getText().trim().length() > 0)
					{
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(SendConsoleToServerCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(SendConsoleToServerCommand.P_COMMAND, txtUser.getText());
						params.put(SendConsoleToServerCommand.P_SERVER, server.getName());
						try 
						{
							ExecutionEvent event = new ExecutionEvent(null, params, me, null);
							StyleRange myStyle = new StyleRange();
							myStyle.foreground = new Color(Display.getDefault(), 0, 150, 0);
							myStyle.start = txtServer.getText().length();
							myStyle.length = txtUser.getText().trim().length();
							txtServer.append(txtUser.getText().trim() + "\n");
							txtServer.setStyleRange(myStyle);
							txtUser.setText("");
							cmd.executeWithChecks(event);					
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
					else
						txtUser.setText("");
				}
			}
			
		
			@Override
			public void keyPressed(KeyEvent e) {
		
			}
		});
		
		clearCmd = new Button(mainComp, SWT.PUSH);
		clearCmd.setText("Clear Log");
		clearCmd.addSelectionListener(new SelectionListener() {
		
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtServer.setText("");
				StyleRange clearStyle = new StyleRange();
				clearStyle.start = 0;
				clearStyle.length = Integer.MAX_VALUE;
				txtServer.setStyleRange(clearStyle);
			}
		
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		
		// restore view if server is available
		if (this.server != null)
			this.setInput(server);

	}

	@Override
	public void setFocus() {
		txtUser.setFocus();
	}
	
	public void appendServerText(String text)
	{
		StyleRange serverStyle = new StyleRange();
		serverStyle.foreground = new Color(Display.getDefault(), 150, 0, 0);
		serverStyle.start = txtServer.getText().length();
		serverStyle.length = text.length();
		txtServer.append(text + "\n");
		txtServer.setStyleRange(serverStyle);
	}

}
